using System;
using System.Linq;
using Charisma.Conventions;
using NUnit.Framework;

namespace Charisma.Tests.Conventions
{
  [TestFixture]
  public class NamedKeyPropertyConventionTests
  {
    public class Document
    {
      public string Id { get; set; }

      public string ID { get; set; }

      public string id { get; set; }

      public string _Id { get; set; }

      public string _ID { get; set; }
      
      public string _id { get; set; }

      public string documentid { get; set; }

      public string DocumentId { get; set; }

      public string DOCUMENTID { get; set; }

      public string document_id { get; set; }

      public string DOCUMENT_ID { get; set; }

      public string Document_Id { get; set; }

      public object Value { get; set; }
    }

    public class Document<T> : Document where T : class 
    {
      public new T Value { get; set; }
    }

    [Test]
    public void RegularClassTest()
    {
      var convention = new NamedKeyMemberConvention();
      var type = typeof(Document);
      var properties = type.GetProperties();

      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "Id")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "ID")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "id")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "_Id")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "_ID")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "_id")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "DocumentId")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "DOCUMENTID")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "documentid")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "Document_Id")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "DOCUMENT_ID")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "document_id")));
      Assert.IsNull(convention.Find(type, properties.Where(p => p.Name == "Value")));
    }

    [Test]
    public void GenericClassTest()
    {
      var convention = new NamedKeyMemberConvention();
      var type = typeof(Document<>);
      var properties = type.GetProperties();

      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "Id")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "ID")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "id")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "_Id")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "_ID")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "_id")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "DocumentId")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "DOCUMENTID")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "documentid")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "Document_Id")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "DOCUMENT_ID")));
      Assert.IsNotNull(convention.Find(type, properties.Where(p => p.Name == "document_id")));
      Assert.IsNull(convention.Find(type, properties.Where(p => p.Name == "Value")));
    }
  }
}